package com.prototype.deep;

import com.google.gson.Gson;

import java.io.*;

// 原型工厂 测试类(克隆应用)
public class Main {
    public static void main(String[] args) throws Exception {

        // TODO 选择方式: 浅克隆 & 深克隆
//         shallowClone();
        deepClone();

    }

    // 浅克隆
    public static void shallowClone() throws Exception {

        // 克隆绵羊对象 & 绵羊对象
        SheepClone sheepClone = new SheepClone();
        Sheep sheep = new Sheep();
        sheep.setName("小绵羊");
        // 封装绵羊
        sheepClone.setSheep(sheep);

        // 克隆
        SheepClone sheepClone2 = sheepClone.clone();
        sheepClone2.getSheep().setName("多莉");

        // 打印
        print(sheepClone, sheepClone2);

        /** 打印结果 (显然可以看出 , 属性对象 地址是一样的
         *   多莉 克隆绵羊!
         *   多莉 克隆绵羊!
         *   sheepClone : 多莉
         *   sheepClone2 : 多莉
         *   sheepClone2 == sheepClone? true
         */
    }

    // 深克隆
    // 克隆方式有多种 : (实现目的重构属性对象新地址
    //  1. 序列化克隆
    //  2. JSON 化克隆
    public static void deepClone(){

        // 克隆绵羊对象 & 绵羊对象
        SheepClone sheepClone = new SheepClone();
        Sheep sheep = new Sheep();
        sheep.setName("小绵羊");
        // 封装绵羊
        sheepClone.setSheep(sheep);

        // TODO 选择方式 : 序列化 & JSON化
        SheepClone sheepClone2 = serializationClone(sheepClone);
//        SheepClone sheepClone2 = jsonClone(sheepClone);

        // 重复值名称
        sheepClone2.getSheep().setName("多莉");

        print(sheepClone, sheepClone2);

        /* 打印结果 (属性对象 地址是不一样的
        *   小绵羊 克隆绵羊!
        *   多莉 克隆绵羊!
        *   sheep : 小绵羊
        *   getSheep2 : 多莉
        *   getSheep == getSheep2? false
        * */
    }

    // 打印数据
    private static void print(SheepClone sheepClone, SheepClone sheepClone2) {
        sheepClone.show();
        sheepClone2.show();
        System.out.println("sheep : " + sheepClone.getSheep().getName());
        System.out.println("getSheep2 : " + sheepClone2.getSheep().getName());
        System.out.println("getSheep == getSheep2? " + (sheepClone.getSheep() == sheepClone2.getSheep()));
    }

    // JSON化克隆
    public static SheepClone jsonClone(SheepClone sheepClone){
        Gson gson = new Gson();
        String str = gson.toJson(sheepClone);
        return gson.fromJson(str , SheepClone.class);
    }

    // 序列化克隆
    public static SheepClone serializationClone(SheepClone sheepClone) {
        // 序列化文件在桌面
        final String path = "C:\\Users\\Sans\\Desktop\\a.txt";
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))
        ) {
            // 写
            oos.writeObject(sheepClone);
            // 读
            return (SheepClone) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
